<!doctype html>



  


<html class="theme-next pisces use-motion">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Courier New:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="gulp," />





  <link rel="alternate" href="/atom.xml" title="Never_yu's Blog" type="application/atom+xml" />




  <link rel="shortcut icon" type="image/x-icon" href="/favicon/favicon.ico?v=5.0.1" />






<meta name="description" content="什么是 gulpgulp 是一个前端构建工具，它能通过自动执行常见任务，比如编译预处理 CSS ，压缩 JavaScript 和刷新浏览器，来改进网站开发的过程，从而使开发更加快速高效。
为什么要用 gulp与 grunt 相比，gulp 无需写一大堆繁杂的配置参数，API（中文 API） 也非常简单，学习起来很容易，而且 gulp 使用的是 nodejs 中 stream 来读取和操作数据，其速">
<meta property="og:type" content="article">
<meta property="og:title" content="gulp 详解与使用">
<meta property="og:url" content="https://neveryu.github.io/2017/05/01/gulp/index.html">
<meta property="og:site_name" content="Never_yu's Blog">
<meta property="og:description" content="什么是 gulpgulp 是一个前端构建工具，它能通过自动执行常见任务，比如编译预处理 CSS ，压缩 JavaScript 和刷新浏览器，来改进网站开发的过程，从而使开发更加快速高效。
为什么要用 gulp与 grunt 相比，gulp 无需写一大堆繁杂的配置参数，API（中文 API） 也非常简单，学习起来很容易，而且 gulp 使用的是 nodejs 中 stream 来读取和操作数据，其速">
<meta property="og:image" content="https://neveryu.github.io/images/gulp-1.png">
<meta property="og:updated_time" content="2017-08-23T14:44:51.257Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="gulp 详解与使用">
<meta name="twitter:description" content="什么是 gulpgulp 是一个前端构建工具，它能通过自动执行常见任务，比如编译预处理 CSS ，压缩 JavaScript 和刷新浏览器，来改进网站开发的过程，从而使开发更加快速高效。
为什么要用 gulp与 grunt 相比，gulp 无需写一大堆繁杂的配置参数，API（中文 API） 也非常简单，学习起来很容易，而且 gulp 使用的是 nodejs 中 stream 来读取和操作数据，其速">
<meta name="twitter:image" content="https://neveryu.github.io/images/gulp-1.png">



<script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Pisces',
    sidebar: {"position":"left","display":"hide"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: undefined,
      author: '博主'
    }
  };
</script>




  <link rel="canonical" href="https://neveryu.github.io/2017/05/01/gulp/"/>


<!-- 网页加载条 -->
<script src="/js/src/pace.min.js"></script>
  <title> gulp 详解与使用 | Never_yu's Blog </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">Never_yu's Blog</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle">认真的人才有资格开玩笑</p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-guestbook">
          <a href="/guestbook" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-commenting"></i> <br />
            
            留言
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-example">
          <a href="/example" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-question-circle"></i> <br />
            
            示例
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
      
      
        <li class="menu-item"> <a title="把这个链接拖到你的工具栏中,任何网页都可以High" href='javascript:(
/*
 * Copyright (C) 2016 Never_yu (Neveryu.github.io) <React.dong.yu@gmail.com>
 * Sina Weibo (http://weibo.com/Neveryu)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
function go() {

var songs = [
  "http://dl.stream.qqmusic.qq.com/C400001Qu4I30eVFYb.m4a?vkey=2127178E4405E7B8B268F20F05232485735CCF4FF8C1432F0360D2626D0B6C9564B5627C7AB481BBC685FEDB0946A50E97C66F0D1B008226&guid=7175649092&uin=0&fromtag=66",
  "",
  "",
  ""
];

function c() {
  var e = document.createElement("link");
  e.setAttribute("type", "text/css");
  e.setAttribute("rel", "stylesheet");
  e.setAttribute("href", f);
  e.setAttribute("class", l);
  document.body.appendChild(e)
}

function h() {
  var e = document.getElementsByClassName(l);
  for (var t = 0; t < e.length; t++) {
    document.body.removeChild(e[t])
  }
}

function p() {
  var e = document.createElement("div");
  e.setAttribute("class", a);
  document.body.appendChild(e);
  setTimeout(function() {
    document.body.removeChild(e)
  }, 100)
}

function d(e) {
  return {
    height : e.offsetHeight,
    width : e.offsetWidth
  }
}

function v(i) {
  var s = d(i);
  return s.height > e && s.height < n && s.width > t && s.width < r
}

function m(e) {
  var t = e;
  var n = 0;
  while (!!t) {
    n += t.offsetTop;
    t = t.offsetParent
  }
  return n
}

function g() {
  var e = document.documentElement;
  if (!!window.innerWidth) {
    return window.innerHeight
  } else if (e && !isNaN(e.clientHeight)) {
    return e.clientHeight
  }
  return 0
}

function y() {
  if (window.pageYOffset) {
    return window.pageYOffset
  }
  return Math.max(document.documentElement.scrollTop, document.body.scrollTop)
}

function E(e) {
  var t = m(e);
  return t >= w && t <= b + w
}

function S() {
  var e = document.getElementById("audio_element_id");
  if(e != null){
    var index = parseInt(e.getAttribute("curSongIndex"));
    if(index > songs.length - 2) {
      index = 0;
    } else {
      index++;
    }
    e.setAttribute("curSongIndex", index);
    N();
  }

  e.src = i;
  e.play()
}

function x(e) {
  e.className += " " + s + " " + o
}

function T(e) {
  e.className += " " + s + " " + u[Math.floor(Math.random() * u.length)]
}

function N() {
  var e = document.getElementsByClassName(s);
  var t = new RegExp("\\b" + s + "\\b");
  for (var n = 0; n < e.length; ) {
    e[n].className = e[n].className.replace(t, "")
  }
}

function initAudioEle() {
  var e = document.getElementById("audio_element_id");
  if(e === null){
    e = document.createElement("audio");
    e.setAttribute("class", l);
    e.setAttribute("curSongIndex", 0);
    e.id = "audio_element_id";
    e.loop = false;
    e.bgcolor = 0;
    e.addEventListener("canplay", function() {
      setTimeout(function() {
        x(k)
      }, 500);
      setTimeout(function() {
        N();
        p();
        for (var e = 0; e < O.length; e++) {
          T(O[e])
        }
      }, 15500)
    }, true);
    e.addEventListener("ended", function() {
      N();
      h();
      go();
    }, true);
    e.innerHTML = " <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>";
    document.body.appendChild(e);
  }
}

initAudioEle();
var e = 30;
var t = 30;
var n = 350;
var r = 350;

var curSongIndex = parseInt(document.getElementById("audio_element_id").getAttribute("curSongIndex"));
var i = songs[curSongIndex];

var s = "mw-harlem_shake_me";
var o = "im_first";
var u = ["im_drunk", "im_baked", "im_trippin", "im_blown"];
var a = "mw-strobe_light";

/* harlem-shake-style.css，替换成你的位置，也可以直接使用：//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake-style.css */
var f = "//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake-style.css";

var l = "mw_added_css";
var b = g();
var w = y();
var C = document.getElementsByTagName("*");
var k = null;
for (var L = 0; L < C.length; L++) {
  var A = C[L];
  if (v(A)) {
    if (E(A)) {
      k = A;
      break
    }
  }
}
if (A === null) {
  console.warn("Could not find a node of the right size. Please try a different page.");
  return
}
c();
S();
var O = [];
for (var L = 0; L < C.length; L++) {
  var A = C[L];
  if (v(A)) {
    O.push(A)
  }
}
})()'><i class="menu-item-icon fa fa-music fa-fw"></i> High一下</a></li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup">
 <span class="search-icon fa fa-search fa-lg"></span>
 <input type="text" id="local-search-input">
 <div id="local-search-result"></div>
 <span class="popup-btn-close">close</span>
</div>


    </div>
  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                gulp 详解与使用
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            <span class="post-meta-item-icon">
              <i class="fa fa-calendar-o"></i>
            </span>
            <span class="post-meta-item-text">发表于</span>
            <time itemprop="dateCreated" datetime="2017-05-01T01:25:24+08:00" content="2017-05-01">
              2017-05-01
            </time>
          </span>

          
            <span class="post-category" >
              &nbsp; | &nbsp;
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="https://schema.org/Thing">
                  <a href="/categories/前端/" itemprop="url" rel="index">
                    <span itemprop="name">前端</span>
                  </a>
                </span>

                
                

              
            </span>
          

          

          

          
          

          
              &nbsp; | &nbsp;
              <span class="page-pv">热度
              <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>℃
              </span>
          
        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h1 id="什么是-gulp"><a href="#什么是-gulp" class="headerlink" title="什么是 gulp"></a>什么是 gulp</h1><p><a href="http://gulpjs.com/" target="_blank" rel="external">gulp</a> 是一个前端构建工具，它能通过自动执行常见任务，比如编译预处理 CSS ，压缩 JavaScript 和刷新浏览器，来改进网站开发的过程，从而使开发更加快速高效。</p>
<h1 id="为什么要用-gulp"><a href="#为什么要用-gulp" class="headerlink" title="为什么要用 gulp"></a>为什么要用 gulp</h1><p>与 grunt 相比，gulp 无需写一大堆繁杂的配置参数，<a href="https://github.com/gulpjs/gulp/blob/master/docs/API.md" target="_blank" rel="external">API</a>（<a href="http://www.gulpjs.com.cn/docs/api/" target="_blank" rel="external">中文 API</a>） 也非常简单，学习起来很容易，而且 gulp 使用的是 nodejs 中 <a href="https://nodejs.org/api/stream.html" target="_blank" rel="external">stream</a> 来读取和操作数据，其速度更快。<br>gulp 有庞大的生态圈，且每天都在发展。依靠成千上万可供选择的插件，你可以利用 gulp 自动完成几乎任何事。</p>
<h1 id="如何使用-gulp"><a href="#如何使用-gulp" class="headerlink" title="如何使用 gulp"></a>如何使用 gulp</h1><h2 id="Installing-Gulp"><a href="#Installing-Gulp" class="headerlink" title="Installing Gulp"></a>Installing Gulp</h2><p>新版的 gulp 命令行工具已经改名为 gulp-cli 。<br>如果你之前安装了全局的 gulp 。在使用新的 gulp-cli 之前，执行命令<br> <code>npm rm --global gulp</code> ，将之前的全局 gulp 卸掉。</p>
<a id="more"></a>
<h3 id="Install-the-gulp-command"><a href="#Install-the-gulp-command" class="headerlink" title="Install the gulp command"></a>Install the gulp command</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --global gulp-cli</span><br></pre></td></tr></table></figure>
<h3 id="Install-gulp-in-your-devDependencies"><a href="#Install-gulp-in-your-devDependencies" class="headerlink" title="Install gulp in your devDependencies"></a>Install gulp in your devDependencies</h3><p>Run this command in your project directory<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev gulp</span><br></pre></td></tr></table></figure></p>
<h2 id="Create-a-gulpfile"><a href="#Create-a-gulpfile" class="headerlink" title="Create a gulpfile"></a>Create a gulpfile</h2><p>Create a file called gulpfile.js in your project root with these contents:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">'gulp'</span>);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">'default'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// place code for your default tash here</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<h2 id="Test-it-out"><a href="#Test-it-out" class="headerlink" title="Test it out"></a>Test it out</h2><p>Run the gulp command in your projct directory:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp</span><br></pre></td></tr></table></figure></p>
<h1 id="gulp-API"><a href="#gulp-API" class="headerlink" title="gulp API"></a>gulp API</h1><p>gulp 的核心 API 有四个：gulp.task() 、 gulp.src() 、 gulp.dest() 、 gulp.watch() 。<br><a href="https://github.com/gulpjs/gulp/blob/master/docs/API.md" target="_blank" rel="external">gulp API</a><br><a href="http://www.gulpjs.com.cn/docs/api/" target="_blank" rel="external">gulp API 中文</a></p>
<p>下面详细介绍一下：</p>
<h2 id="gulp-src"><a href="#gulp-src" class="headerlink" title="gulp.src()"></a>gulp.src()</h2><p>gulp.src() 可以读取你需要操作的文件，相比于 Grunt 主要以文件为媒介来运行它的工作流，gulp 使用的是 Nodejs 中的 <a href="https://nodejs.org/api/stream.html" target="_blank" rel="external">stream</a> 流，首先获取到需要的 stream ，然后可以通过 stream 的 pipe() 方法把流导入到你想要的地方，比如 gulp 的插件中，经过插件处理后的流又可以继续导入到其他插件中，当然也可以把流写入到文件中。所以 gulp 是以 stream 为媒介的，它不需要频繁的生成临时文件，这也是 gulp 的速度比 Grunt 快的一个原因。再回到正题上来，gulp.src() 方法正是用来获取流的，但要注意这个流里的内容不是原始的文件流，而是一个虚拟文件对象流（Vinyl files），这个虚拟文件对象中存储着原始文件的路径、文件名、内容等信息，这个我们暂时不用去深入理解，你只需简单的理解可以用这个方法来读取你需要操作的文件就行了。其语法为：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp.src(globs [, options])</span><br></pre></td></tr></table></figure></p>
<p>gulp 用到的 glob 的匹配规则以及一些文件匹配技巧。<br>gulp 内部使用了 node-glob 模块来实现其文件匹配功能。我们可以使用下面这些特殊的字符来匹配我们想要的文件：</p>
<ul>
<li><code>*</code> 匹配文件路径中的 0 个或多个字符，但不会匹配路径分配符，除非路径分隔符出现在末尾</li>
<li>** 匹配路径中的 0 个或多个目录及其子目录，需要单独出现，即它左右不能有其他东西了。如果出现在末尾，也能匹配文件。</li>
<li>? 匹配文件路径中的一个字符（不会匹配路径分隔符）</li>
<li>[…] 匹配方括号中出现的字符中的任意一个，当方括号中第一个字符为 ^ 或 ! 时，则表示不匹配方括号中出现的其他字符中的任意一个，类似 js 正则表达式中的用法。</li>
<li>!(pattern|pattern|pattern) 匹配任何与括号中给定的任一模式都不匹配的</li>
<li>?(pattern|pattern|pattern) 匹配括号中给定的任一模式 0 次或 1 次，类似于 js 正则中的(pattern|pattern|pattern)?</li>
<li>+(pattern|pattern|pattern) 匹配括号中给定的任一模式至少 1 次，类似于正则中的(pattern|pattern|pattern)+</li>
<li><code>*(pattern|pattern|pattern)</code> 匹配括号中的给定的任一模式 0 次或多次，类似于 js 正则中的 <code>(pattern|pattern|pattern)*</code></li>
<li>@(pattern|pattern|pattern) 匹配括号中给定的任一模式 1 次，类似于 js 正则中的(pattern|pattern|pattern)</li>
</ul>
<p>下面以一系列例子来加深理解</p>
<ul>
<li><code>*</code> 能匹配 a.js 、 x.y 、 abc 、 abc/ ，但不能匹配 a/b.js</li>
<li><code>*.*</code> 能匹配 a.js 、 style.css 、 a.b 、 x.y</li>
<li><code>*/*/*.js</code> 能匹配 a/b/c.js 、 x/y/z.js ，不能匹配 a/b.js 、a/b/c/d.js</li>
<li>** 能匹配 abc 、 a/b.js 、 a/b/c.js 、 x/y/z 、x/y/z/a.b ，能用来匹配所有的目录和文件</li>
<li><em>*/</em>.js 能匹配 foo.js 、 a/foo.js 、 a/b/foo.js 、 a/b/c/foo.js</li>
<li>a/**/z 能匹配 a/z 、 a/b/z 、 a/b/c/z 、 a/d/g/h/r/z</li>
<li><code>a/**b/z</code> 能匹配 a/b/z 、 a/fb/z ，但不能匹配 a/x/gb/z ，因为只有单 ** 单独出现才能匹配多级目录</li>
<li>?.js 能匹配 a.js 、 b.js 、 c.js</li>
<li>a?? 能匹配 a.b 、 abc ，但不能匹配 ab/ ，因为它不会匹配路径分隔符</li>
<li>[xyz].js 只能匹配 x.js 、 y.js 、 z.js ，不会匹配 xy.js 、 xyz.js 等，整个中括号只代表一个字符</li>
<li>[^xyz].js 能匹配 a.js 、 b.js 、 c.js 等，不能匹配 x.js 、 y.js 、 z.js</li>
</ul>
<p>当有多种匹配模式时可以使用数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用数组的方式来匹配多种文件</span></span><br><span class="line">gulp.src([<span class="string">'js/*.js'</span>,<span class="string">'css/*.css'</span>,<span class="string">'*.html'</span>])</span><br></pre></td></tr></table></figure></p>
<p>使用数组的方式还有一个好处就是可以很方便的使用排除模式，在数组中的单个匹配模式前加上 ! 即是排除模式，它会在匹配的结果中排除这个匹配，要注意一点的是不能在数组中的第一个元素中使用排除模式<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gulp.src([*.js,<span class="string">'!b*.js'</span>])  <span class="comment">//匹配所有 js 文件，但排除掉以 b 开头的 js 文件</span></span><br><span class="line">gulp.src([<span class="string">'!b*.js'</span>,*.js])  <span class="comment">//不会排除任何文件，因为排除模式不能出现在数组的第一个元素中</span></span><br></pre></td></tr></table></figure></p>
<p>此外，还可以使用展开模式。展开模式以花括号作为定界符，根据它里面的内容，会展开为多个模式，最后匹配的结果为所有展开的模式想加起来得到的结果。展开的例子如下：</p>
<ul>
<li>a{b,c}d 会展开为 abd 、 acd</li>
<li>a{b,}c 会展开为 abc 、 ac</li>
<li>a{0..3}d 会展开为 a0d 、 a1d 、 a2d 、 a3d </li>
<li>a{b,c{d,e}f}g 会展开为 abg 、 acdfg 、 acefg</li>
<li>a{b,c}d{e,f}g 会展开为 abdeg 、 acdeg 、 abdfg 、 abdeg</li>
</ul>
<h2 id="gulp-dest"><a href="#gulp-dest" class="headerlink" title="gulp.dest()"></a>gulp.dest()</h2><p>gulp.dest() 方法是用来写文件的，其语法为：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp.dest(path[, options])</span><br></pre></td></tr></table></figure></p>
<p><strong>path</strong> 为写入文件的路径<br>我们给 gulp.dest() 传入的路径参数，只能用来指定要生成的文件的目录，而不能指定生成文件的文件名，它生成文件的文件名使用的是导入到它的文件流自身的文件名，所以生成的文件名是由导入到它的文件流决定的，即使我们给它传入一个带有文件名的路径参数，然后它也会把这个文件名当作是目录名，例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">"gulp"</span>);</span><br><span class="line">gulp.src(<span class="string">"script/jquery.js"</span>).pipe(gulp.dest(<span class="string">"dist/foo.js"</span>));</span><br><span class="line"><span class="comment">// 最终生成的文件路径为 dist/foo.js/jquery.js ，而不是 dist/foo.js</span></span><br></pre></td></tr></table></figure></p>
<p>要想改变文件名，可以使用插件 gulp-rename<br>下面说说生成的文件路径与我们给 gulp.dest() 方法传入的路径参数之间的关系。<br>gulp.dest(path) 生成的文件路径是我们传入的 path 参数后面再加上 gulp.src() 中有通配符开始出现的那部分路径。例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">"gulp"</span>);</span><br><span class="line"><span class="comment">//有通配符开始出现的那部分路径为 **/*.js</span></span><br><span class="line">gulp.src(<span class="string">"script/**/*.js"</span>).pipe(gulp.dest(<span class="string">"dist"</span>));</span><br><span class="line"><span class="comment">//最后生成的文件路径为 dist/**/*.js</span></span><br><span class="line"><span class="comment">//如果 **/*.js 匹配到的文件为 jquery/jquery.js ，则生成的文件路径为 dist/jquery/jquery.js</span></span><br></pre></td></tr></table></figure></p>
<p>再举更多一点的例子<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">gulp.src(<span class="string">"script/avalon/avalon.js"</span>).pipe(gulp.dest(<span class="string">"dist"</span>));</span><br><span class="line"><span class="comment">//没有通配符出现的情况，最后生成的文件路径为 dist/avalon.js</span></span><br><span class="line"></span><br><span class="line">gulp.src(<span class="string">"script/**/underscore.js"</span>).pipe(gulp.dest(<span class="string">"dist"</span>));</span><br><span class="line"><span class="comment">//有通配符开始出现的那部分路径为 **/underscore.js</span></span><br><span class="line"><span class="comment">//假设匹配到的文件为script/util/underscore.js</span></span><br><span class="line"><span class="comment">//则最后生成的文件路径为dist/util/underscore.js</span></span><br><span class="line"></span><br><span class="line">gulp.src(<span class="string">"script/*"</span>).pipe(gulp.dest(<span class="string">"dist"</span>));</span><br><span class="line"><span class="comment">//有通配符出现的那部分路径为*</span></span><br><span class="line"><span class="comment">//假设匹配到的文件为script/zepto.js</span></span><br><span class="line"><span class="comment">//则最后生成的文件路径为dist/zepto.js</span></span><br></pre></td></tr></table></figure></p>
<p>通过指定 gulp.src() 方法配置参数中的 base 属性，我们可以灵活的来改变 gulp.dest() 生成的文件路径。<br>当我们没有在 gulp.src() 方法配置参数中的 base 属性，base 的默认值为通配符开始出现之前那部分路径，例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp.src(<span class="string">"app/src/**/*.css"</span>) <span class="comment">//此时base的值为 app/src</span></span><br></pre></td></tr></table></figure></p>
<p>上面我们说的 gulp.dest() 所生成的文件路径的规则，其实也可以理解成，用我们给 gulp.dest() 传入的路径替换掉 gulp.src() 中的 base 路径，最终得到生成文件的路径。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">gulp.src(<span class="string">"app/src/**/*.css"</span>).pipe(gulp.dest(<span class="string">"dist"</span>));</span><br><span class="line"><span class="comment">//此时base的值为app/src，也就是说它的base路径为app/src</span></span><br><span class="line"><span class="comment">//设该模式匹配到了文件app/src/css/normal.css</span></span><br><span class="line"><span class="comment">//用dist替换掉base路径，最终得到dist/css/normal.css</span></span><br></pre></td></tr></table></figure></p>
<p>所以改变 base 路径后，gulp.dest() 生成的文件路径也会改变<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">gulp.src(<span class="string">"script/lib/*.js"</span>).pipe(gulp.dest(<span class="string">"build"</span>));</span><br><span class="line"><span class="comment">//没有配置base参数，此时默认的base路径为script/lib</span></span><br><span class="line"><span class="comment">//假设匹配到的文件为script/lib/jquery.js</span></span><br><span class="line"><span class="comment">//生成的文件路径为build/jquery.js</span></span><br><span class="line"></span><br><span class="line">gulp.src(<span class="string">"script/lib/*.js"</span>, &#123;<span class="attr">base</span>: <span class="string">"script"</span>&#125;).pipe(gulp.dest(<span class="string">"build"</span>));</span><br><span class="line"><span class="comment">//配置了base参数，此时base路径为script</span></span><br><span class="line"><span class="comment">//假设匹配到的文件为script/lib/jquery.js</span></span><br><span class="line"><span class="comment">//此时生成的文件路径为build/lib/jquery.js</span></span><br></pre></td></tr></table></figure></p>
<p>用 gulp.dest() 把文件流写入文件后，文件流仍然可以继续使用。</p>
<h2 id="gulp-task"><a href="#gulp-task" class="headerlink" title="gulp.task()"></a>gulp.task()</h2><p>gulp.task 方法用来定义任务，内部使用的是 Orchestrator ，其语法为：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(name[, deps], fn)</span><br></pre></td></tr></table></figure></p>
<p><strong>name</strong> 为任务名，如果你需要在命令行中运行你的某些任务，那么，请不要在名字中使用空格。<br><strong>deps</strong> 是当前定义的任务需要依赖的其他任务，为一个数组。当前定义的任务会在所有依赖的任务执行完毕后才开始执行。如果没有依赖，则可省略这个参数。<br><strong>fn</strong> 为任务函数，我们把任务要执行的代码都要写在里面。该参数也是可选的。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(<span class="string">"mytask"</span>, [<span class="string">"array"</span>, <span class="string">"of"</span>, <span class="string">"task"</span>, <span class="string">"names"</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">//定义一个有依赖的任务</span></span><br><span class="line">  <span class="comment">// Do something</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>关于 gulp.task() ，我们需要知道执行多个任务时怎么来控制任务执行的顺序。<br>gulp 中执行多个任务，可以通过任务依赖来实现。例如我想要执行 one ，two ，three 这三个任务，那我们就可以定义一个空的任务，然后把那三个任务当做这个空的任务的依赖就行了：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//只要执行default任务，就相当于把one,two,three这三个任务执行了</span></span><br><span class="line">gulp.task(<span class="string">'default'</span>,[<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>]);</span><br></pre></td></tr></table></figure></p>
<p>如果任务相互之间没有依赖，任务会按你书写的顺序来执行，如果有依赖的话则会先执行依赖的任务。<br>但是如果某个任务所依赖的任务是异步的，就要注意了，gulp 并不会等待那个所依赖的异步任务完成，而是会接着执行后续的任务。例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(<span class="string">'one'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="comment">// one是一个异步执行的任务</span></span><br><span class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"one is done"</span>);</span><br><span class="line">  &#125;,<span class="number">3000</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//two任务虽然依赖于one任务，但并不会等到one任务中的异步操作完成后再执行</span></span><br><span class="line">gulp.task(<span class="string">"two"</span>, [<span class="string">"one"</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">"two is done"</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p><img src="/images/gulp-1.png" alt=""><br>上面的例子中我们执行 two 任务时，会先执行 one 任务，但不会去等待 one 任务中的异步操作完成后再执行 two 任务，而是紧接着执行 two 任务。因为 one 任务耗时 3 秒，所以 two 任务会在 one 任务中的异步操作完成之前就执行了。</p>
<p>那如果我们想等待异步任务中的异步操作完成后再执行后续的任务，该怎么做呢？<br>有三种方法可以实现：</p>
<p>第一：在异步操作完成后执行一个回调函数来通知 gulp 这个异步任务已经完成，这个回调函数就是任务函数的第一个参数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(<span class="string">"one"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">cb</span>) </span>&#123;</span><br><span class="line">  <span class="comment">//cb为任务函数提供的回调，用来通知任务已经完成</span></span><br><span class="line">  <span class="comment">//one是一个异步执行的任务</span></span><br><span class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"one is done"</span>);</span><br><span class="line">    cb(); <span class="comment">//执行回调，表示这个异步任务已经完成</span></span><br><span class="line">  &#125;,<span class="number">5000</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//这时two任务会在one任务中的异步操作完成后再执行</span></span><br><span class="line">gulp.task(<span class="string">"two"</span>, [<span class="string">"one"</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">"two is done"</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>第二：定义任务时返回一个流对象。适用于任务就是操作 gulp.src 获取到的流的情况。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(<span class="string">"one"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">cb</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> stream = gulp.src(<span class="string">"client/**/*.js"</span>)</span><br><span class="line">      .pipe(dosomething()) <span class="comment">//dosomething()中有某些异步操作</span></span><br><span class="line">      .pipe(gulp.dest(<span class="string">"build"</span>));</span><br><span class="line">  <span class="keyword">return</span> stream;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 这是two任务会在one任务中的异步操作完成后再执行</span></span><br><span class="line">gulp.task(<span class="string">"two"</span>, [<span class="string">"one"</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">"two is done"</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>第三：返回一个 promise 对象，例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Q = <span class="built_in">require</span>(<span class="string">'q'</span>); <span class="comment">//一个著名的异步处理的库 https://github.com/kriskowal/q</span></span><br><span class="line">gulp.task(<span class="string">"one"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">cb</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> deferred = Q.defer();</span><br><span class="line">  <span class="comment">//做一些异步操作</span></span><br><span class="line">  setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    deferred.resolve();</span><br><span class="line">  &#125;,<span class="number">5000</span>);</span><br><span class="line">  <span class="keyword">return</span> deferred.promise;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.task(<span class="string">"two"</span>, [<span class="string">"one"</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">"two is done"</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>关于 gulp.task() ，主要的就是要清除当依赖异步任务时要如何处理。</p>
<h2 id="gulp-watch"><a href="#gulp-watch" class="headerlink" title="gulp.watch()"></a>gulp.watch()</h2><p>gulp.watch() 用来监视文件的变化，当文件发生变化后，我们可以利用它来执行相应的任务，例如文件压缩等。其语法为：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp.watch(glob[, opts], tasks);</span><br></pre></td></tr></table></figure></p>
<p><strong>glob</strong> 为要监视的文件匹配模式，规则和用法与 gulp.src() 方法中的 glob 相同。<br><strong>opts</strong> 为一个可选的配置对象，通常不需要用到。<br><strong>tasks</strong> 为文件变化后要执行的任务，为一个数组<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">gulp.task(<span class="string">"uglify"</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">//do something</span></span><br><span class="line">&#125;);</span><br><span class="line">gulp.task(<span class="string">"reload"</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">//do something</span></span><br><span class="line">&#125;);</span><br><span class="line">gulp.watch(<span class="string">"js/**/*.js"</span>, [<span class="string">"uglify"</span>,<span class="string">"reload"</span>]);</span><br></pre></td></tr></table></figure></p>
<p>gulp.watch(glob [,opts, cb])<br><strong>glob</strong> 和 <strong>opts</strong> 参数与第一种用法相同<br><strong>cb</strong> 参数为一个函数。每当监视的文件发生变化时，就会调用这个函数，并且会给它传入一个对象，该对象包含了文件变化的一些信息，type 属性为变化的类型，可以是 added 、changed 、deleted ，path 属性为发生变化的文件的路径<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">gulp.watch(<span class="string">"js/**/*.js"</span>, <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(event.type); <span class="comment">//变化类型added为新增，deleted为删除，changed为改变</span></span><br><span class="line">  <span class="built_in">console</span>.log(event.path); <span class="comment">//变化的文件的路径</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<h1 id="gulp-的插件"><a href="#gulp-的插件" class="headerlink" title="gulp 的插件"></a>gulp 的插件</h1><p>gulp 本身虽然不能完成很多任务，但它有大量插件可用，我们可以在 <a href="http://gulpjs.com/plugins/" target="_blank" rel="external">插件页面</a> 或者在 npm 搜索 gulpplugin 。<br>列一些很棒的 plugin ：</p>
<ul>
<li><a href="https://www.npmjs.com/package/gulp-jshint/" target="_blank" rel="external">JSHint</a> ： js代码检查分析工具</li>
<li><a href="https://www.npmjs.com/package/gulp-coffee/" target="_blank" rel="external">gulp-coffee</a> ： 编译CoffeeScript</li>
<li><a href="https://www.npmjs.com/package/gulp-mocha" target="_blank" rel="external">gulp-mocha</a> ： 执行Mocha测试</li>
<li><a href="https://www.npmjs.com/package/gulp-bump" target="_blank" rel="external">gulp-bump</a> ： 更新版本号</li>
<li><a href="https://www.npmjs.com/package/gulp-sass" target="_blank" rel="external">gulp-sass</a> ： sass 编译</li>
<li><a href="http://www.browsersync.cn/docs/gulp/" target="_blank" rel="external">browser-sync</a> ： 浏览器自动刷新</li>
<li><a href="https://www.npmjs.com/package/gulp-uglify" target="_blank" rel="external">gulp-uglify</a> ： 代码压缩</li>
<li><a href="https://www.npmjs.com/package/gulp-concat" target="_blank" rel="external">gulp-concat</a> ： 合并</li>
<li><a href="https://www.npmjs.com/package/gulp-eslint" target="_blank" rel="external">gulp-eslint</a> ： 支持 ES6 JSX</li>
</ul>
<h1 id="gulp-命令行参数"><a href="#gulp-命令行参数" class="headerlink" title="gulp 命令行参数"></a>gulp 命令行参数</h1><ul>
<li><code>-v</code> 或 <code>--version</code> 会显示全局和项目本地所安装的 gulp 版本号</li>
<li><code>--require &lt;module path&gt;</code> 将会在执行之前 require 一个模块。这对于一些语言编译器或者需要其他应用的情况来说很有用。你可以使用多个 <code>--require</code></li>
<li><code>--gulpfile &lt;gulpfile path&gt;</code> 手动指定一个 gulpfile 的路径，这在你有很多个 gulpfile 的时候很有用。这也会将 CWD 设置到该 gulpfile 所在目录</li>
<li><code>--cwd &lt;dir path&gt;</code> 手动指定 CWD 。定义 gulpfile 查找的位置，此外，所有的相应的依赖（require）会从这里开始计算相对路径</li>
<li><code>-T</code> 或 <code>--tasks</code> 会显示所指定 gulpfile 的 task 依赖树</li>
<li><code>--tasks-simple</code> 会以纯文本的方式显示所载入的 gulpfile 中的 task 列表</li>
<li><code>--color</code> 强制 gulp 和 gulp 插件显示颜色，即便没有颜色支持</li>
<li><code>--no-color</code> 强制不显示颜色，即便检测到有颜色支持</li>
<li><code>--silent</code> 禁止所有的 gulp 日志</li>
</ul>
<p>命令行会在 process.env.INIT_CW 中记录它是从哪里被运行的。</p>
<h1 id="tip"><a href="#tip" class="headerlink" title="tip"></a>tip</h1><p>1、gulp 写进项目 package.json 文件的依赖有什么作用<br>方便别人查看你项目中有些什么依赖，而且在项目目录下执行 npm install 命令会安装项目 package.json 中的所有依赖模块，这样就能简化项目的安装程序了，不用一个一个模块去安装啊。</p>
<p>2、gulp 中着重了解 gulp.task() 如何处理依赖任务是耗时操作或者异步操作的情况。</p>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

<blockquote class="blockquote-center" style="color: #ccc;">
    -------------本文结束 <i class="fa fa-apple"></i> 感谢您的阅读-------------
</blockquote>

  <span id="inline-green" style="border-radius:3px;">作者</span>：<a class="link-blue" href="https://github.com/Neveryu" target="_blank">Neveryu</a><br/>有问题请 <a class="link-blue" href="https://neveryu.github.io/guestbook" target="_blank">留言</a> 或者私信我的 <a class="link-blue" href="http://weibo.com/Neveryu" target="_blank">微博</a>。

  <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
    <div>满分是10分的话，这篇文章你给几分</div>
    <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
      <span>赏</span>
    </button>
    <div id="QR" style="display: none;">
      
        <div id="wechat" style="display: inline-block">
          <img id="wechat_qr" src="/reward/reward_wechat.png" alt="Never_yu WeChat Pay"/>
          <p>微信打赏</p>
        </div>
      
      
        <div id="alipay" style="display: inline-block">
          <img id="alipay_qr" src="/reward/reward_alipay.png" alt="Never_yu Alipay"/>
          <p>支付宝打赏</p>
        </div>
      
    </div>
  </div>


      
    </div>

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/gulp/" rel="tag"><i class="fa fa-tag"></i> gulp</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/04/10/npm/" rel="next" title="npm 全面介绍">
                <i class="fa fa-chevron-left"></i> npm 全面介绍
              </a>
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/05/20/npm-two/" rel="prev" title="npm 的一个小细节">
                npm 的一个小细节 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
        <!-- JiaThis Button BEGIN -->
<div class="jiathis_style">
  <a class="jiathis_button_tsina"></a>
  <a class="jiathis_button_tqq"></a>
  <a class="jiathis_button_weixin"></a>
  <a class="jiathis_button_cqq"></a>
  <a class="jiathis_button_douban"></a>
  <a class="jiathis_button_renren"></a>
  <a class="jiathis_button_qzone"></a>
  <a class="jiathis_button_kaixin001"></a>
  <a class="jiathis_button_copy"></a>
  <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank"></a>
  <a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" >
  var jiathis_config={
    hideMore:false
  }
</script>
<script type="text/javascript" src="http://v3.jiathis.com/code/jia.js" charset="utf-8"></script>
<!-- JiaThis Button END -->

      
    </div>
  </div>


          </div>
          


          
        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/avatar/avatar.png"
               alt="Never_yu" />
          <p class="site-author-name" itemprop="name">Never_yu</p>
          <p class="site-description motion-element" itemprop="description">Stay Hungry,Stay Foolish</p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">36</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">4</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">19</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        
          <div class="feed-link motion-element">
            <a href="/atom.xml" rel="alternate">
              <i class="fa fa-rss"></i>
              RSS
            </a>
          </div>
        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/Neveryu" target="_blank" title="Github">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  Github
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/Neveryu" target="_blank" title="Weibo">
                  
                    <i class="fa fa-fw fa-weibo"></i>
                  
                  Weibo
                </a>
              </span>
            
          
        </div>

        
        
          <div class="cc-license motion-element" itemprop="license">
            <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" target="_blank">
              <img src="/images/cc-by-nc-sa.svg" alt="Creative Commons" />
            </a>
          </div>
        

        
        
          <div class="links-of-blogroll motion-element links-of-blogroll-inline">
            <div class="links-of-blogroll-title">
              <i class="fa  fa-fw fa-globe"></i>
              友情链接
            </div>
            <ul class="links-of-blogroll-list">
              
                <li class="links-of-blogroll-item">
                  <a href="https://codeigniter.org.cn/" title="CodeIgniter中国" target="_blank">CodeIgniter中国</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="/weblog" title="建站日志" target="_blank">建站日志</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="http://blog.csdn.net/csdn_yudong" title="CSDN" target="_blank">CSDN</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="https://neveryu.github.io/neveryu" title="个人首页" target="_blank">个人首页</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="/reward" title="打赏" target="_blank">打赏</a>
                </li>
              
            </ul>
          </div>
        
      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#什么是-gulp"><span class="nav-number">1.</span> <span class="nav-text">什么是 gulp</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#为什么要用-gulp"><span class="nav-number">2.</span> <span class="nav-text">为什么要用 gulp</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#如何使用-gulp"><span class="nav-number">3.</span> <span class="nav-text">如何使用 gulp</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Installing-Gulp"><span class="nav-number">3.1.</span> <span class="nav-text">Installing Gulp</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Install-the-gulp-command"><span class="nav-number">3.1.1.</span> <span class="nav-text">Install the gulp command</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Install-gulp-in-your-devDependencies"><span class="nav-number">3.1.2.</span> <span class="nav-text">Install gulp in your devDependencies</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Create-a-gulpfile"><span class="nav-number">3.2.</span> <span class="nav-text">Create a gulpfile</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Test-it-out"><span class="nav-number">3.3.</span> <span class="nav-text">Test it out</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#gulp-API"><span class="nav-number">4.</span> <span class="nav-text">gulp API</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#gulp-src"><span class="nav-number">4.1.</span> <span class="nav-text">gulp.src()</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#gulp-dest"><span class="nav-number">4.2.</span> <span class="nav-text">gulp.dest()</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#gulp-task"><span class="nav-number">4.3.</span> <span class="nav-text">gulp.task()</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#gulp-watch"><span class="nav-number">4.4.</span> <span class="nav-text">gulp.watch()</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#gulp-的插件"><span class="nav-number">5.</span> <span class="nav-text">gulp 的插件</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#gulp-命令行参数"><span class="nav-number">6.</span> <span class="nav-text">gulp 命令行参数</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#tip"><span class="nav-number">7.</span> <span class="nav-text">tip</span></a></li></ol></div>
            
          </div>
        </section>
      

      
        <section style="border-top:1px dotted #ccc; padding-top:10px;">
          <iframe width="100%" height="120" class="share_self"  frameborder="0" scrolling="no" src="https://widget.weibo.com/weiboshow/index.php?language=&width=0&height=120&fansRow=2&ptype=1&speed=0&skin=5&isTitle=1&noborder=1&isWeibo=0&isFans=0&uid=5346488237&verifier=d529ff3a&dpc=1"></iframe>
        </section>
      
    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        

<div class="busuanzi-count">

  <!-- <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script> -->
  <!-- 上面这个是之前的，不知道为什么失效了，改成下面这个 -->
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

  
    <span class="site-uv">您是第<span class="busuanzi-value" id="busuanzi_value_site_uv"></span>个小伙伴</span>
  

  
    <span class="site-pv">本站总浏览<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>次</span>
  
  
</div>



        <div class="copyright" >
  
  &copy;  2016 - 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Never_yu</span>
</div>

<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io" rel="external nofollow">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next" rel="external nofollow">
    NexT.Pisces
  </a>
</div>

<div class="theme-info">
  <div class="powered-by"></div>
  <span class="post-count" style="color: #e90f92;">全站共 156k 字</span>
</div>
        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.0.1"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.0.1"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.1"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.0.1"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.1"></script>



  



  




  
  
  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length == 0) {
       search_path = "search.xml";
    }
    var path = "/" + search_path;
    // monitor main search box;

    function proceedsearch() {
      $("body").append('<div class="popoverlay">').css('overflow', 'hidden');
      $('.popup').toggle();

    }
    // search function;
    var searchFunc = function(path, search_id, content_id) {
    'use strict';
    $.ajax({
        url: path,
        dataType: "xml",
        async: true,
        success: function( xmlResponse ) {
            // get the contents from search data
            isfetched = true;
            $('.popup').detach().appendTo('.header-inner');
            var datas = $( "entry", xmlResponse ).map(function() {
                return {
                    title: $( "title", this ).text(),
                    content: $("content",this).text(),
                    url: $( "url" , this).text()
                };
            }).get();
            var $input = document.getElementById(search_id);
            var $resultContent = document.getElementById(content_id);
            $input.addEventListener('input', function(){
                var matchcounts = 0;
                var str='<ul class=\"search-result-list\">';
                var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                $resultContent.innerHTML = "";
                if (this.value.trim().length > 1) {
                // perform local searching
                datas.forEach(function(data) {
                    var isMatch = true;
                    var content_index = [];
                    var data_title = data.title.trim().toLowerCase();
                    var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase();
                    var data_url = data.url;
                    var index_title = -1;
                    var index_content = -1;
                    var first_occur = -1;
                    // only match artiles with not empty titles and contents
                    if(data_title != '' && data_content != '') {
                        keywords.forEach(function(keyword, i) {
                            index_title = data_title.indexOf(keyword);
                            index_content = data_content.indexOf(keyword);
                            if( index_title < 0 && index_content < 0 ){
                                isMatch = false;
                            } else {
                                if (index_content < 0) {
                                    index_content = 0;
                                }
                                if (i == 0) {
                                    first_occur = index_content;
                                }
                            }
                        });
                    }
                    // show search results
                    if (isMatch) {
                        matchcounts += 1;
                        str += "<li><a href='"+ data_url +"' class='search-result-title'>"+ data_title +"</a>";
                        var content = data.content.trim().replace(/<[^>]+>/g,"");
                        if (first_occur >= 0) {
                            // cut out 100 characters
                            var start = first_occur - 20;
                            var end = first_occur + 80;
                            if(start < 0){
                                start = 0;
                            }
                            if(start == 0){
                                end = 50;
                            }
                            if(end > content.length){
                                end = content.length;
                            }
                            var match_content = content.substring(start, end);
                            // highlight all keywords
                            keywords.forEach(function(keyword){
                                var regS = new RegExp(keyword, "gi");
                                match_content = match_content.replace(regS, "<b class=\"search-keyword\">"+keyword+"</b>");
                            });

                            str += "<p class=\"search-result\">" + match_content +"...</p>"
                        }
                        str += "</li>";
                    }
                })};
                str += "</ul>";
                if (matchcounts == 0) { str = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>' }
                if (keywords == "") { str = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>' }
                $resultContent.innerHTML = str;
            });
            proceedsearch();
        }
    });}

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched == false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };

    });

    $('.popup-btn-close').click(function(e){
      $('.popup').hide();
      $(".popoverlay").remove();
      $('body').css('overflow', '');
    });
    $('.popup').click(function(e){
      e.stopPropagation();
    });
  </script>


  

  

  
<script type="text/javascript" async src="//push.zhanzhang.baidu.com/push.js">
</script>


  <!-- 按需加载背景 -->
  <!-- 背景动画 -->
<script type="text/javascript">
  // 按需加载背景
  // 如果是all，就直接加载了
  if("pc" == "all") {
    $.getScript("/js/src/particle.js?v=5.0.1");
  }
  // 识别手机或电脑的js开始
  (function(){
    var res = GetRequest();
    var par = res['index'];
    if(par!='gfan'){
      var ua=navigator.userAgent.toLowerCase();
      var contains=function (a, b){
          if(a.indexOf(b)!=-1){return true;}
      };
      if((contains(ua,"android") && contains(ua,"mobile"))||(contains(ua,"android") && contains(ua,"mozilla"))||(contains(ua,"android") && contains(ua,"opera"))||contains(ua,"ucweb7")||contains(ua,"iphone")){
        return false;
      } else {
        $.getScript("/js/src/particle.js?v=5.0.1");
      }
    }
  })();
  function GetRequest() {
    var url = location.search;
    var theRequest = new Object();
    if (url.indexOf("?") != -1) {
      var str = url.substr(1);
      strs = str.split("&");
      for(var i = 0; i < strs.length; i ++) {
        theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
      }
    }
    return theRequest;
  }
</script>
<!-- 识别手机或电脑的js结束 -->  

  <!-- 页面点击小红心 -->
  <!-- 页面点击小红心 -->

  <script type="text/javascript" src="/js/src/love.js?v=5.0.1"></script>


  <!-- 鼠标移动，效果 -->
  <!-- 鼠标移动特效 -->

  <script type="text/javascript" src="/js/src/jquery-stars.js?v=5.0.1"></script>
  <script type="text/javascript">
  jQuery('body').jstars({
  	image_path: '/images',
  	image: 'candy-cane-stars.png',
  	style: 'white',
  	width: 34,
  	height: 34,
  	delay: 700,
  	frequency: 5
  });
  </script>


  <!-- 页面 title 进入/离开 效果 -->

  <script type="text/javascript">var OriginTitile=document.title,st;document.addEventListener("visibilitychange",function(){document.hidden?(document.title="≡[。。]≡ 回不去了吗？!",clearTimeout(st)):(document.title="(ฅ>ω<*ฅ) Thank Vue~ "+OriginTitile,st=setTimeout(function(){document.title=OriginTitile},4e3))})</script>


</body>
</html>
